// npx babel-node map_demo01.js

const {log} = console;
let _ = null;

let test01 = function() {
    let _;

    const m = new Map();
    const o = { p: 'Hello World'};

    m.set(o, 'content');
    _ = m.get(o);
    console.log(_);

    _ = m.has(o);
    console.log(_);

    _ = m.delete(o);
    console.log(_);

    _ = m.has(o);
    console.log(_);
}

// test01();

let test02 = function() {
    let _;
    const map = new Map([
        ['name', '张三'],
        ['title', 'Author']
    ]);

    _ = map.size;
    console.log(_);

    _ = map.has('name');
    log(_);

    _ = map.get('name');
    log(_);

    _ = map.has('title');
    log(_);

    _ = map.get('title');
    log(_);
}

// test02();


let test03 = function() {
    const items = [
        ['name', '张三'],
        ['title', 'Author']
    ];

    const map = new Map();

    items.forEach(
        ([key, value]) => map.set(key, value)
    );

    log(map);
};

// test03();


let test04 = function() {
    const set = new Set([
        ['foo', 1],
        ['bar', 2]
    ]);
    const m1 = new Map(set);
    _ = m1.get('foo')
    log(_);

    const m2 = new Map([['baz', 3]]);
    const m3 = new Map(m2);
    _ = m3.get('baz')
    log(_);
};

// test04();


let test05 = function() {
    const map = new Map();

    map
        .set(1, 'aaa')
        .set(1, 'bb');

    _ = map.get(1)
    log(_);
};

// test05();

// 注意，只有对同一个对象的引用，Map 结构才将其视为同一个键。这一点要非常小心。

let test06 = function() {
    const map = new Map();

    map.set(['a'], 555);
    _ = map.get(['a']);
    log(_);
};

// test06();

let test07 = function() {
    const map = new Map();

    const k1 = ['a'];
    const k2 = ['a'];

    map.set(k1, 111).set(k2, 222);

    _ = map.get(k1);
    log(_);

    _ = map.get(k2);
    log(_);
};

// test07();

let test08 = function() {
    const map = new Map();

    map.set('foo', true);
    map.set('bar', false);

    _ = map.size;
    log(_);
};

// test08();

let test09 = function() {
    const m = new Map();

    m.set('edition', 6);
    m.set(262, 'standard');
    m.set(undefined, 'nah');

    log(m);
};

// test09();

let test10 = function() {
    const m = new Map();

    const hello = function() { console.log('hello'); };
    m.set(hello, 'Hello ES6!');

    _ = m.get(hello);
    log(_);
};

// test10();

let test11 = function(){
    const m = new Map();

    m.set('edition', 6)
     .set(262, 'standard')
     .set(undefined, 'nah');

    _ = m.has('edition');
    log(_)

    _ = m.has('years')
    log(_);

    _ = m.has(262);
    log(_);

    _ = m.has(undefined);
    log(_);
};

// test11();

let test12 = function(){
    const m = new Map();
    m.set(undefined, 'nah');
    _ = m.has(undefined);
    log(_);

    m.delete(undefined);
    _ = m.has(undefined);
    log(_);
};

// test12();

let test13 = function() {
    const map = new Map();
    _ = map[Symbol.iterator] === map.entries;
    log(_);
};

// test13();

let test14 = function() {
    const map = new Map([
        [1, 'one'],
        [2, 'two'],
        [3, 'three'],
    ]);

    _ = [...map.keys()]
    log(_)

    _ = [...map.values()]
    log(_)

    _ = [...map.entries()]
    log(_)

    _ = [...map]
    log(_)
};

// test14();

let test15 = function(){
    const map0 = new Map()
        .set(1, 'a')
        .set(2, 'b')
        .set(3, 'c');
    
    log(map0);

    const map1 = new Map(
        [...map0].filter(([k, v]) => k < 3)
    );

    log(map1);

    const map2 = new Map(
        [...map0].map(([k, v]) => [k * 2, '_' + v])
    );
    log(map2);
};

// test15();

let test16 = function() {
    const map = new Map([
        [1, 'one'],
        [2, 'two'],
        [3, 'three'],
    ]);

    map.forEach(function(value, key, map){
        log("key: %s, Value: %s", key, value);
    });
};

// test16();

let test17 = function() {
    const map = new Map([
        [1, 'one'],
        [2, 'two'],
        [3, 'three'],
    ]);

    const reporter = {
        report: function(key, value) {
            log("key: %s, value: %s", key, value);
        }
    };

    map.forEach(function(val, key, map){
        this.report(key, val);
    }, reporter);
};

// test17();

function strMapToObj(strMap) {
    let obj = Object.create(null);
    for(let [k, v] of strMap) {
        obj[k] = v;
    }
    return obj;
}

let test18 = function() {
    const myMap = new Map()
        .set('yes', true)
        .set('no', false);

    _ = strMapToObj(myMap);
    log(_);
};

// test18();

let test19 = function(){
    let obj = {"a":1, 'b':2};
    let map = new Map(Object.entries(obj));
    log(map);
};

// test19();

function strMapToJson(strMap) {
    return JSON.stringify(strMapToObj(strMap));
}

let test20 = function(){
    let myMap = new Map().set('yes', true)
        .set('no', false);
    _ = strMapToJson(myMap);
    log(_);
};

// test20();

function mapToArrayJson(map) {
    return JSON.stringify([...map]);
}

let test21 = function(){
    let myMap = new Map().set(true, 7)
        .set({foo: 3}, ['abc']);
    _ = mapToArrayJson(myMap);
    log(_);
};

test21();





